export interface StartPostion {
  startX: number;
  startY: number;
  startLeft: number;
  startTop: number;
}

export interface DragElOptions {
  container: HTMLElement; // 需要拖拽移动的元素
  dragHandeler?: HTMLElement; // 在拖拽元素中的拖动的位置
  onDragStart?: (ev: MouseEvent, startPos: StartPostion) => void; // 鼠标按下拖动开始
  onDrag?: (ev: MouseEvent, startPos: StartPostion) => void; // 鼠标按下拖动过程
  onDragEnd?: (ev: MouseEvent, startPos: StartPostion) => void; // 鼠标抬起拖动结束
}

export function registerDragElement(options: DragElOptions, isPrevent = false) {
  const {
    container,
    dragHandeler = container,
    onDragStart,
    onDrag,
    onDragEnd,
  } = options;

  // 是否准备拖动
  let isDragging = false;
  // 记录鼠标位置
  let startX = 0;
  let startY = 0;
  // 记录元素位置
  let startLeft = 0;
  let startTop = 0;

  const onMousedown = (ev: MouseEvent) => {
    isDragging = true;

    const { clientX: x, clientY: y } = ev;

    startX = x;
    startY = y;
    startLeft = container.offsetLeft;
    startTop = container.offsetTop;

    dragHandeler.style.cursor = "move";

    onDragStart?.(ev, {
      startX,
      startY,
      startLeft,
      startTop,
    });
  };

  const onMousemove = (ev: MouseEvent) => {
    if (!isDragging) return;

    const { clientX: x, clientY: y } = ev;
    const deltaX = x - startX;
    const deltaY = y - startY;

    // 是否禁止拖拽移动
    if (!isPrevent) {
      container.style.left = `${startLeft + deltaX}px`;
      container.style.top = `${startTop + deltaY}px`;
    }

    onDrag?.(ev, {
      startX,
      startY,
      startLeft,
      startTop,
    });
  };

  const onMouseup = (ev: MouseEvent) => {
    if (isDragging) {
      isDragging = false;
      dragHandeler.style.cursor = "pointer";
      onDragEnd?.(ev, {
        startX,
        startY,
        startLeft,
        startTop,
      });
    }
  };

  dragHandeler.addEventListener("mousedown", onMousedown, false);
  document.addEventListener("mousemove", onMousemove, false);
  document.addEventListener("mouseup", onMouseup, false);

  return () => {
    dragHandeler.removeEventListener("mousedown", onMousedown, false);
    document.removeEventListener("mousemove", onMousemove, false);
    document.removeEventListener("mouseup", onMouseup, false);
  };
}
